<template>
	<view>
		<uv-button v-if="fileList.length < max" :color="bgColor" :icon="icon ? icon : iconUplaod" icon-color="#fff"
			:icon-size="icon ? '40rpx' : '28rpx'" :text="text" :throttle-time="3000" custom-style="width: 630rpx"
			@click="checkClockInRange" />
		<view v-if="fileList.length > 0" class="img-list">
			<view v-for="(item, index) in fileList" :key="index" class="img-item">
				<view class="img-del" @click="deletePic(index)">
					<uv-icon name="close" color="#fff" />
				</view>
				<image :src="webSrc(item.url)" mode="aspectFill" @click="previewImage(item.url)" />
				<view class="argin" v-if="item.status == 'fail'">
					<text @click="addWatermark(index)">重新上传</text>
				</view>
				<canvas :canvas-id="'mark' + index" :style="{
            width: (item.width || 300) + 'px',
            height: (item.height || 300) + 'px',
          }" />
			</view>
		</view>
	</view>
</template>
<script setup>
	import {
		ref,
		watch
	} from "vue";
	import {
		commonUpload
	} from "@/request/common.js";
	import {
		isClockInRange
	} from "@/request/task";
	import {
		webSrc,
		timeFormat
	} from "@/common/mothed.js";
	import iconUplaod from "@/static/login/icon_uplaod.png";
	const props = defineProps({
		// 上传图片
		value: {
			type: [Array, String],
			default: [],
		},
		// 图标
		icon: {
			type: String,
			default: "",
		},
		// 按钮文字
		text: {
			type: String,
			default: "上传",
		},
		// 背景色
		bgColor: {
			type: String,
			default: "#4EA770",
		},
		// 最大上传数
		max: {
			type: [Number, String],
			default: 1,
		},
		// 时间水印
		timeMark: {
			type: Boolean,
			default: false,
		},
		// 地址水印
		addressMark: {
			type: Boolean,
			default: false,
		},
		// 是否离线
		offlineMode: {
			type: Boolean,
			default: false,
		}
	});

	const fileList = ref([]); // 文件列表
	const uploadFail = ref(false); // 上传失败
	const emit = defineEmits(["update:value", "state"]);

	watch(
		props,
		(val) => {
			fileList.value = val.value.map((i) => {
				return {
					url: i,
					status: "success",
				};
			});
		}, {
			deep: true,
			immediate: true
		}
	);

	// 选择图片
	const handleChooseImage = () => {
		uni.chooseImage({
			count: props.max - fileList.value.length,
			sizeType: ["original", "compressed"],
			success: async (image) => {
				for (let i = 0; i < image.tempFilePaths.length; i++) {
					let temp = image.tempFilePaths[i];
					if (props.offlineMode) {
						let path = await formatImage(temp);
						fileList.value.push({ url: path, status: "success" });
						uploadFail.value = false;
						emit("state", { noBack: uploadFail.value, state: "success" });
						emit("update:value", fileList.value.map((a) => a.url));
					} else {
						commonUpload(temp).then((res) => {
							if (res.code == 200) {
								fileList.value.push({ url: res.fileName, status: "success" });
								uploadFail.value = false;
								emit("state", { noBack: uploadFail.value, state: "success" });
								emit("update:value", fileList.value.map((a) => a.url));
							}
						});
					}
				}
			},
			fail: () => {
				uni.showToast({
					title: "获取权限失败",
					icon: "none",
				})
			}
		});
		
		return
		uni.chooseImage({
			count: props.max - fileList.value.length, // 最大上传数
			sizeType: ["compressed"], // original 原图，compressed 压缩图
			sourceType: ["camera", "album"], // 使用相机 相册
			success: async (res) => {
				try {
					uploadFail.value = true;
					emit("state", {
						noBack: uploadFail.value,
						state: "start",
					});
					const filePromises = res.tempFilePaths.map(async (i) => {
						let info = await getImageSize(i);
						return info;
					});

					const fileInfos = await Promise.all(filePromises);
					fileList.value = fileList.value.concat(fileInfos);
					fileList.value.forEach((item, index) => {
						addWatermark(index);
					});
				} catch (err) {
					console.error('上传异常', err);
				}
			},
			fail: () => {
				uni.showToast({
					title: "获取权限失败",
					icon: "none",
				})
			}
		});
	};

	// 转换图片格式
	const formatImage = (tempFilePath) => {
		return new Promise((resolve, reject) => {
			uni.saveFile({
				tempFilePath: tempFilePath,
				success: (saveRes) => {
					resolve(saveRes.savedFilePath);
				},
				fail: (err) => {
					resolve(tempFilePath);
				},
			});
		})
	}

	// 检测是否在打卡范围内
	const checkClockInRange = () => {
		// #ifdef APP-PLUS
		if (props.offlineMode) {
			handleChooseImage();
		} else {
			uni.getLocation({
				type: "gcj02",
				success: (pos) => {
					let data = {
						resourceId: uni.getStorageSync("subPlanId"),
						latitude: pos.latitude,
						longitude: pos.longitude,
					};
					isClockInRange(data).then((res) => {
						if (res.data) {
							handleChooseImage();
						} else {
							uni.showToast({
								title: "超出作业范围",
								icon: "none",
							});
						}
					});
				},
				fail: (e) => {
					setTimeout(() => {
						checkClockInRange();
					}, 1000);
				},
			});
		}
		// #endif
		// #ifdef H5
		handleChooseImage();
		// #endif
	};

	// 获取初始图片尺寸
	const getImageSize = (url) => {
		return new Promise((resolve) => {
			uni.getImageInfo({
				src: url,
				success: (image) => {
					resolve({
						url,
						width: image.width,
						height: image.height,
						status: "loading",
					});
				},
			});
		});
	};

	// 添加水印
	const addWatermark = (index) => {
		const imageUrl = fileList.value[index].url;
		const ctx = uni.createCanvasContext("mark" + index);
		uni.getImageInfo({
			src: imageUrl,
			success: async (image) => {
				fileList.value[index] = {
					url: imageUrl,
					width: image.width,
					height: image.height,
					status: "loading",
				};
				// 绘制原始图片
				ctx.drawImage(imageUrl, 0, 0, image.width, image.height);
				ctx.setFontSize(0.0375 * image.width);
				ctx.setFillStyle("rgba(255, 255, 255, 0.6)");
				ctx.setTextAlign("right");
				if (props.timeMark) {
					ctx.fillText(
						timeFormat(new Date(), "yyyy-mm-dd hh:MM:ss"),
						image.width - (0.0375 * image.width),
						image.height - 20
					);
				}

				if (props.addressMark) {
					// #ifdef APP-PLUS
					let adx = await getLocation();
					ctx.fillText(adx, image.width - (0.0375 * image.width), (0.07 * image.width));
					// #endif
					// #ifdef H5
					ctx.fillText(
						`H5不支持定位信息，仅供样式参考`,
						image.width - (0.0375 * image.width),
						image.height - (0.07 * image.width)
					);
					// #endif
				}
				
				
				ctx.draw(false, () => {
					uni.canvasToTempFilePath({
						canvasId: "mark" + index,
						success: async (img) => {
							await uploadFilePromise(img.tempFilePath, index).then((
								res) => {
									if (res.code == 200) {
										fileList.value[index] = {
											url: res.fileName,
											width: image.width,
											height: image.height,
											status: "success",
										};
										if (fileList.value.every((i) => i.status ==
												"success")) {
											uploadFail.value = false;
											emit("state", {
												noBack: uploadFail.value,
												state: "success",
											});
											emit(
												"update:value",
												fileList.value.map((i) => i
													.url)
											);
										} else {
											uploadFail.value = true;
											emit("state", {
												noBack: uploadFail.value,
												state: "loading",
											});
										}
									}
								});
						},
					});
				});
			},
		});
	};

	// 获取定位信息
	const getLocation = () => {
		return new Promise((resolve) => {
			uni.getLocation({
				type: "gcj02",
				geocode: true,
				success: (res) => {
					if (res.address) {
						const {
							province,
							city,
							district,
							street,
							streetNum
						} = res.address;
						resolve(`${province}${city}${district}${street}${streetNum}`);
					}
				},
				fail: () => {
					resolve("定位失败");
				},
			});
		});
	};

	// 删除图片
	const deletePic = (index) => {
		uni.showModal({
			title: "提示",
			content: "确定是否删除？",
			showCancel: true,
			success: ({
				confirm
			}) => {
				if (confirm) {
					fileList.value.splice(index, 1);
					emit(
						"update:value",
						fileList.value.map((i) => i.url)
					);
					if (fileList.value.every((i) => i.status == "success")) {
						uploadFail.value = false;
						emit("state", {
							noBack: uploadFail.value,
							state: "success",
						});
					}
				}
			},
		});
	};

	// 预览图片
	const previewImage = (url) => {
		uni.previewImage({
			urls: [webSrc(url)],
			current: webSrc(url),
		});
	};

	// 上传凭证图片
	const uploadFilePromise = (url, index) => {
		return new Promise((resolve) => {
			commonUpload(url)
				.then((res) => {
					if (res.code == 200) {
						setTimeout(() => {
							resolve(res);
						}, 1000);
					}
				})
				.catch(() => {
					uploadFail.value = true;
					fileList.value[index].status = "fail";
					emit("state", {
						noBack: uploadFail.value,
						state: "fail",
					});
				});
		});
	};
</script>
<style lang="scss" scoped>
	.img-list {
		display: grid;
		grid-template-columns: repeat(3, 1fr);
		gap: 20rpx;
		width: 630rpx;
		margin-top: 20rpx;

		.img-item {
			position: relative;
			height: 200rpx;
			overflow: hidden;
			border-radius: 8rpx;
			background: rgba(0, 0, 0, 0.1);

			.img-del {
				position: absolute;
				top: 0;
				right: 0;
				width: 42rpx;
				height: 42rpx;
				background: rgba(0, 0, 0, 0.5);
				border-radius: 0 8rpx 0 8rpx;
				display: flex;
				align-items: center;
				justify-content: center;
				z-index: 1;
			}

			image {
				width: 100%;
				height: 100%;
			}

			.argin {
				position: absolute;
				top: 0;
				left: 0;
				right: 0;
				bottom: 0;
				background: rgb(0 0 0 / 31%);
				text-align: center;
				font-size: 14px;
				color: #f0f0f0;
				display: flex;
				align-items: center;
				justify-content: center;
			}
		}
	}
</style>